function testCreateE34Element() {
  var elem = e34.$("testClassOperationsDiv");
  assertNotUndefined("Creating an e34 element with a valid ID should return an object.", elem);
};

function testCreateE34ElementThrowsErrorOnBadInput() {
  try {
    var elem = e34.$("dafdsfadsfadsf");
    fail("Creating an e34 element with an invalid object should throw an Error.");
  } catch (err) {
    assertNotUndefined("Error should have a message", err.message);
  }
};

function testHasClass() {
  var elem = e34.$("testClassOperationsDiv");
  assertTrue("Has class should return true when the element has the class.", elem.hasClass("testclass"));
  assertFalse("Has class should return false when the element does not have the class", elem.hasClass("teasdafdssadf"));
};

function testAddClass() {
  var className = new Date().getTime();
  var elem = e34.$("testClassOperationsDiv");
  assertFalse("The test element should have the class before we add it.", elem.hasClass(className));
  elem.addClass(className);
  assertTrue("The test element should have the class after we add it.", elem.hasClass(className));
};

function testRemoveClass() {
  var className = new Date().getTime();
  var elem = e34.$("testClassOperationsDiv");
  elem.addClass(className);
  assertTrue("The test element should have the class before we remove it.", elem.hasClass(className));
  elem.removeClass(className);
  assertFalse("The test element should not have the class after we remove it.", elem.hasClass(className));
};

function test$() {
  var result1 = e34.$("testClassOperationsDiv");
  assertNotNull("$ should return an element given a valid ID.", result1);
  assertEquals("$ should return the element with the given string ID.", result1.getElement().id, "testClassOperationsDiv");
  
  var gel_elem = document.getElementById("testClassOperationsDiv");
  var result2 = e34.$(gel_elem);
  assertNotNull("$ should return an element given a valid Element.", result2);
  assertEquals("$ should return the element specified by the given Element.", result2.getElement().id, "testClassOperationsDiv");

  var e34_elem = e34.$("testClassOperationsDiv");
  var result3 = e34.$(e34_elem);
  assertNotNull("$ should return an element given a valid e34 object.", result3);
  assertEquals("$ should return the e34 object specified by the given e34 object.", result3.getElement().id, "testClassOperationsDiv");
};

function test$C() {
  var testClassOperationsDiv = e34.$("testClassOperationsDiv");
  assertNotNull("Test div should exist", testClassOperationsDiv);
  var testUl = e34.$("testCDollarUL");
  assertNotNull("Test ul should exist", testUl);
  
  var test1Results = e34.$C("classA");
  assertNotNull("$C should always return an array.", test1Results);
  assertEquals("$C should return all the items on the page with the given class.", 5, test1Results.length);
  
  var test2Results = e34.$C("classA", "span");
  assertNotNull("$C should always return an array.", test2Results);
  assertEquals("$C should only return items matching the supplied tag.", 3, test2Results.length);
  
  var test3Results = e34.$C("classA", "span", testUl);
  assertNotNull("$C should always return an array.", test3Results);
  assertEquals("$C should only return items matching the supplied tag under the given root.", 1, test3Results.length);
};

function testRenderTemplate() {  
  var stringTemplate = "<div id='div1'><span id='val1' class='test'>@value1@</span><span id='val2'>@value2@</span></div>";
  var data = {
    "value1": "I am value number one",
    "value2": "Value2!"
  };
  var result = e34.renderTemplate(stringTemplate, data);
  assertNotNull("renderTemplate should return an e34 object", result);
  assertNotNull("renderTemplate should construct an e34 object from a string template.", 
      result.getElement().childNodes[0]);
  assertEquals("renderTemplate should correctly construct DOM nodes from a string template.", 
      "test", result.getElement().childNodes[0].className);
  
  var domTemplate = document.getElementById("testRenderTemplateDiv");
  result = e34.renderTemplate(domTemplate, data);
  assertNotNull("renderTemplate should return an e34 object", result);
  assertNotNull("renderTemplate should construct an e34 object from a DOM template.", 
      result.getElement().childNodes[0]);
  assertEquals("renderTemplate should correctly construct DOM nodes from a DOM template.", 
      "test", result.getElement().childNodes[0].className);
  
  var e34Template = e34.$("testRenderTemplateDiv");
  result = e34.renderTemplate(e34Template, data);
  assertNotNull("renderTemplate should return an e34 object", result);
  assertNotNull("renderTemplate should construct an e34 object from an e34 template.", 
      result.getElement().childNodes[0]);
  assertEquals("renderTemplate should correctly construct DOM nodes from an e34 template.", 
      "test", result.getElement().childNodes[0].className);
};

function testSerializeElement_() {
  var elem = e34.$("testDiv");
  var result1 = e34.serializeElement_(elem);
  var match1 = ('<div id="testDiv" class="testclass"></div>' == result1) ||
               ('<DIV class=testclass id=testDiv></DIV>' == result1);
  assertTrue("serializeElement should return a string representation of an e34 element.", match1);

  var result2 = e34.serializeElement_("testDiv");
  var match2 = ('<div id="testDiv" class="testclass"></div>' == result2) ||
               ('<DIV class=testclass id=testDiv></DIV>' == result2);
  assertTrue("serializeElement should return a string representation of an element specified by ID.", match2);
  
  var result3 = e34.serializeElement_(document.getElementById("testDiv"));
  var match3 = ('<div id="testDiv" class="testclass"></div>' == result3) ||
               ('<DIV class=testclass id=testDiv></DIV>' == result3);
  assertTrue("serializeElement should return a string representation of a DOM element.", match3);
  
};

function testSerializeElement_HandlesTableRows() {
  var result = e34.serializeElement_("testRow1");
  var match = ('<tr id="testRow1"><td>Test</td></tr>' == result) ||
              ('<TR id=testRow1> <TD>Test</TD></TR>' == result.replace(/\s+/g, " "));
  assertTrue("serializeElement should return a string representation of table rows.", match);  
};

function testSerializeElement_HandlesAttributesWithSpaces() {
  var result = e34.serializeElement_("test Div");
  var match = ('<div id="test Div" class="testclass"></div>' == result) ||
              ('<DIV class=testclass id="test Div"></DIV>' == result);
  assertTrue("serializeElement should return a string representation of elements with spaces in the attributes", match);  
};

function testRenderStringTemplateCreatesTableRows() {
  var stringTemplate = "<tr class='tablerowclass'><td>@data1@</td></tr>";
  var data = {
    "data1": "I am value number one"
  };
  var result1 = e34.renderTemplate(stringTemplate, data);
  assertNotNull("renderStringTemplate should create an element when given a table row template.", result1);
  assertEquals("renderStringTemplate should create a table row.", "TR", result1.getTagName());
};

function testRenderStringTemplateCreatesOptions() {
  var stringTemplate = "<option value='@value@'>@text@</option>";
  var data = {
    "value": "testvalue",
    "text": "testtext"
  };
  var result1 = e34.renderTemplate(stringTemplate, data);
  assertNotNull("renderStringTemplate should create an element when given an option element.", 
      result1);
  assertEquals("renderStringTemplate should create an option.", 
      "OPTION", result1.getTagName());
  assertEquals("renderStringTemplate should create an option with the correct value.", 
      "testvalue", result1.getElement().value);
};

function testRenderStringTemplateStripsRootID() {
  var stringTemplate = "<div id='div1'><span id='val1' class='test'>@value1@</span><span id='val2'>@value2@</span></div>";
  var data = {
    "value1": "I am value number one",
    "value2": "Value2!"
  };
  var result = e34.renderTemplate(stringTemplate, data);
  assertEquals("renderStringTemplate should strip the ID of the template root node.", 
      "", result.getElement().id);
};

function testRenderStringTemplateSubstitutesDataValues() {
  var stringTemplate = "<div id='div1'><span id='val1' class='test'>@value1@</span><span id='val2'>@value2@</span></div>";
  var data = {
    "value1": "I am value number one",
    "value2": "Value2!"
  };
  var result = e34.renderTemplate(stringTemplate, data);
  assertEquals("renderStringTemplate should correctly substitute data values from a template.", 
      "I am value number one", result.getElement().childNodes[0].innerHTML);
};

function exposeTestFunctionNames() {
  return [
    "testCreateE34Element",
    "testCreateE34ElementThrowsErrorOnBadInput",
    "testHasClass",
    "testAddClass",
    "testRemoveClass",
    "test$",
    "test$C",
    "testRenderTemplate",
    "testSerializeElement_",
    "testSerializeElement_HandlesTableRows",
    "testSerializeElement_HandlesAttributesWithSpaces",
    "testRenderStringTemplateCreatesTableRows",
    "testRenderStringTemplateCreatesOptions",
    "testRenderStringTemplateStripsRootID",
    "testRenderStringTemplateSubstitutesDataValues"
  ];
};

